package com.mcjtf.prefix.service;

import com.google.common.collect.Maps;
import com.mcjtf.prefix.PrefixManager;
import com.mcjtf.prefix.model.User;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class ConfigService {
    public static boolean checkUpdate;
    public static int SAVE_PERIOD;
    public static boolean USE_NAMETAG;
    public static String PREFIX;

    public final Map<String, YamlConfiguration> dataCache = Maps.newHashMap();
    private final PrefixManager plugin;

    public ConfigService() {
        this.plugin = PrefixManager.getInstance();

        plugin.saveDefaultConfig();
        plugin.reloadConfig();

        File dataFile = new File(plugin.getDataFolder() + "/data/");
        if (!dataFile.getParentFile().exists()) {
            dataFile.getParentFile().mkdirs();
        }

        loadConfig();
        loadGroup();
    }

    public void reload() {
        loadConfig();
        loadGroup();
    }

    public void addPrefix(String name, List<String> prefix) {
        dataCache.get(name).set(name + ".prefix", prefix);
    }

    public void addSuffix(String name, List<String> suffix) {
        dataCache.get(name).set(name + ".suffix", suffix);
    }

    public void loadPlayer(Player p) {
        String name = p.getName();
        File file = new File(plugin.getDataFolder() + "/data/" + name + ".yml");
        boolean isNew = !file.exists();

        User user = new User(name);
        user.setUuid(p.getUniqueId());
        user.setGroup(plugin.getVaultHook().getGroup(p));
        if (isNew) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                plugin.getLogger().info(e.getMessage());
            }
            user.addPrefix(plugin.getVaultHook().getPrefix(p));
            user.addSuffix(plugin.getVaultHook().getSuffix(p));
            if (plugin.groups.containsKey("p_" + user.getGroup()))
                user.setGroupPrefix(plugin.groups.get("p_" + user.getGroup()));
            if (plugin.groups.containsKey("s_" + user.getGroup()))
                user.setGroupSuffix(plugin.groups.get("s_" + user.getGroup()));
            savePlayer(user);
        } else {
            YamlConfiguration d = YamlConfiguration.loadConfiguration(file);
            user.setUuid(p.getUniqueId());
            user.setPrefixes(d.getStringList(name + ".prefix"));
            user.setSuffixes(d.getStringList(name + ".suffix"));
            user.setUsePrefix(d.getInt(name + ".In-use.prefix"));
            user.setUseSuffix(d.getInt(name + ".In-use.suffix"));
        }
        plugin.getPrefixService().getUserMap().put(name, user);
        user.refresh();
        if (user.getDisplayName().length() <= 16) {
            p.setPlayerListName(user.getDisplayName());
        }
        dataCache.put(p.getName(), YamlConfiguration.loadConfiguration(file));
    }

    public boolean loadOfflinePlayer(String name, String world) {
        File file = new File(plugin.getDataFolder() + "/data/" + name + ".yml");
        if (!file.exists()) {
            return false;
        }
        YamlConfiguration d = YamlConfiguration.loadConfiguration(file);
        if (!d.contains(name)) {
            return false;
        }
        User user = new User(name);
        user.setPrefixes(d.getStringList(name + ".prefix"));
        user.setSuffixes(d.getStringList(name + ".suffix"));
        user.setUsePrefix(d.getInt(name + ".In-use.prefix"));
        user.setUseSuffix(d.getInt(name + ".In-use.suffix"));
        user.setGroup(plugin.getVaultHook().getGroup(name, world));
        user.refresh();
        plugin.getPrefixService().getUserMap().put(name, user);
        dataCache.put(name, d);
        return true;
    }

    public boolean hasPlayer(String name) {
        File file = new File(plugin.getDataFolder() + "/data/" + name + ".yml");
        return file.exists();
    }

    public void saveAll() {
        for (Entry<String, User> e : plugin.getPrefixService().getUserMap().entrySet()) {
            savePlayer(e.getKey());
        }
    }

    public void savePlayer(String name) {
        User user = plugin.getPrefixService().getUserMap().get(name);
        File file = new File(plugin.getDataFolder() + "/data/" + name + ".yml");
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                plugin.getLogger().info(e.getMessage());
            }
        }
        YamlConfiguration data = YamlConfiguration.loadConfiguration(file);
        if (user.getUuid() != null)
            data.set(name + ".uuid", user.getUuid().toString());
        if (user.getGroup() != null)
            data.set(name + ".group", user.getGroup());
        data.set(name + ".prefix", user.getPrefixes());
        data.set(name + ".suffix", user.getSuffixes());
        data.set(name + ".In-use.prefix", user.getUsePrefix());
        data.set(name + ".In-use.suffix", user.getUseSuffix());
        try {
            data.save(file);
        } catch (IOException e) {
            plugin.getLogger().info(e.getMessage());
        }
    }

    public void savePlayer(User user) {
        String name = user.getName();
        File file = new File(plugin.getDataFolder() + "/data/" + name + ".yml");
        YamlConfiguration data = YamlConfiguration.loadConfiguration(file);
        if (data.contains(name + ".uuid"))
            data.set(name + ".uuid", user.getUuid().toString());
        if (user.getGroup() != null)
            data.set(name + ".group", user.getGroup());
        data.set(name + ".prefix", user.getPrefixes());
        data.set(name + ".suffix", user.getSuffixes());
        data.set(name + ".In-use.prefix", user.getUsePrefix());
        data.set(name + ".In-use.suffix", user.getUseSuffix());
        try {
            data.save(file);
        } catch (IOException e) {
            plugin.getLogger().info(e.getMessage());
        }
    }

    public void checkGroupPrefix(User user) {
        List<String> l1 = plugin.groups.get("p_" + user.getGroup());
        List<String> l2 = user.getGroupPrefix();
        if (l1.containsAll(l2) && l2.containsAll(l1)) {
            for (String n : l2) {
                if (!user.getPrefixes().contains(n))
                    user.getPrefixes().add(n);
            }
        } else {
            user.getPrefixes().removeAll(l2);
            user.getPrefixes().addAll(l1);
            user.setGroupPrefix(l1);
            if (user.getUsePrefix() + 1 > user.getPrefixes().size())
                user.setUsePrefix(0);
        }
    }

    private void loadGroup() {
        File file = new File(plugin.getDataFolder() + "/group.yml");
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                plugin.getLogger().info(e.getMessage());
            }
        }
        YamlConfiguration g = YamlConfiguration.loadConfiguration(file);
        if (g.contains("groups")) {
            for (String n : g.getConfigurationSection("groups").getKeys(false)) {
                if (g.contains("groups." + n + ".prefix"))
                    plugin.groups.put("p_" + n, g.getStringList("groups." + n + ".prefix"));
                if (g.contains("groups." + n + ".suffix"))
                    plugin.groups.put("s_" + n, g.getStringList("groups." + n + ".suffix"));
            }
        }
    }

    private void loadConfig() {
        FileConfiguration config = plugin.getConfig();
        checkUpdate = config.getBoolean("checkUpdate", true);
        for (String n : config.getConfigurationSection("setting.format").getKeys(false)) {
            n = n.toLowerCase();
            plugin.format.put(n, config.getString("setting.format." + n));
        }
        if (!plugin.format.containsKey("default")) {
            config.set("setting.format.default", "&e<&6[DISPLAYNAME]&e> &7[MESSAGE]");
            plugin.format.put("default", "&e<&6[DISPLAYNAME]&e> &7[MESSAGE]");
        }
        PREFIX = config.getString("setting.prefix").replace('&', '§');
        USE_NAMETAG = config.getBoolean("setting.name_tag");
        SAVE_PERIOD = config.getInt("setting.save_interval");
    }
}
